ESP

您所在的位置:网站首页 lwip udp通信 ESP

ESP

2023-03-16 13:43| 来源: 网络整理| 查看: 265



一、ESP32 IDF的TCP/IP协议栈

TCP/IP协议栈是ESP32 IDF的一个核心组件。它实现了TCP、UDP、IP、DHCP、DNS和其他网络协议,使ESP32可以与其他设备通信。具体来说,ESP32 IDF的TCP/IP协议栈包括以下几个主要模块: 1. WiFi协议栈 2. TCP/IP协议栈 3. LWIP协议栈 4. SPI Flash文件系统 通过TCP/IP协议栈,ESP32可以轻松地实现各种网络应用,例如HTTP服务器、MQTT客户端、TCP/UDP服务器和客户端等等。同时,ESP32 IDF提供了丰富的API和组件,使得开发人员可以快速地实现自己的应用程序。

ESP32主要使用LwIP协议栈,支持函数: - BSD风格 Sockets API - Netconn API (未正式启用)

官方文档提示: 在使用任何lwIP API(除BSD Sockets API之外)时,请确保它是线程安全的。 要检查特定的API调用是否安全,请启用CONFIG_LWIP_CHECK_THREAD_SAFETY并运行应用程序。这样,lwIP会断言TCP/IP核心功能被正确访问,如果没有正确锁定或从正确的任务(lwIP FreeRTOS任务)访问,则执行中止。 一般建议使用ESP-NETIF组件与lwIP交互。

ESP-IDF对lwIP进行了一些封装,以间接支持部分功能,如: - DHCP - SNTP - ICMP Ping - NetBIOS查找可使用的lwIP API - mDNS - 串行PPP接口 等。

二、BSD套接字API介绍

BSD Sockets API 是一个常见的跨平台TCP/IP套接字API, 有时被称为POSIX Sockets或 Berkeley Sockets。

lwIP支持BSD Sockets API的所有常见用法,一些功能如下: - socket() - bind() - accept() - shutdown() - getpeername() - getsockopt() - setsockopt() - close() - read(), readv() write() writev() - recv() recvmsg() recfrom() - send() sendmsg() sendto() - select() - poll() - fcntl() 另外lwIP还支持ioctl()非标准的功能。

三、创建TCP Server的步骤1. 引用TCP/IP协议栈

在CMakeLists.txt包含以下内容:

idf_component_register(SRCS "your_source_files.c" INCLUDE_DIRS "include" REQUIRES "tcpip_adapter")2. 创建 TCP套接字拼绑定端口

创建一个TCP套接字,并将其绑定到指定的端口。然后使用listen()函数将服务器套接字设置为侦听连接。

#include #include #include #include #include #define PORT CONFIG_EXAMPLE_PORT static struct sockaddr_in server_addr; static int server_socket = -1; void create_tcp_server() { server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (server_socket 在这里插入图片描述

1. wifi.h#ifndef WIFI_LIB #define WIFI_LIB #include /* 宏定义 */ #include #include "esp_log.h" #define LIGHT_ESP_WIFI_SSID "你的wifi账号" #define LIGHT_ESP_WIFI_PASS "你的wifi密码" #define LIGHT_ESP_MAXIMUM_RETRY 5 // 事件组允许每个事件有多个位,这里只使用两个事件: // 已经连接到AP并获得了IP // 在最大重试次数后仍未连接 #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 /* 函数声明 */ void wifi_initialize(void); void wifi_station_initialize(void); void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); #endif /* WIFI_LIB */2. wifi.c#include #include "main/network/include/wifi.h" #include #include static const char *TAG = "wifi lib"; // FreeRTOS事件组,连接成功时发出信号 static EventGroupHandle_t s_wifi_event_group = NULL; static int s_retry_num = 0; // 事件回调 void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { // 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_START if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { esp_wifi_connect(); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { // 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_DISCONNECTED /* 如果重试次数小于最大重试次数 */ if (s_retry_num ip_info.ip)); // 将重试次数重置为 0; s_retry_num = 0; // 通过调用 xEventGroupSetBits 函数,将 WIFI_CONNECTED_BIT 设置到事件组中,表示成功连接到 AP xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } } void wifi_initialize(void) { // 创建一个事件组,用于管理Wi-Fi连接事件。 s_wifi_event_group = xEventGroupCreate(); // 初始化 TCP/IP 协议栈。 ESP_ERROR_CHECK(esp_netif_init()); // 创建默认事件循环。 ESP_ERROR_CHECK(esp_event_loop_create_default()); // 创建默认的Wi-Fi网络接口。 esp_netif_create_default_wifi_sta(); // 设置 Wi-Fi 初始化配置为默认配置 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); // 注册事件处理器,以处理 Wi-Fi 和 IP 相关事件 ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); } void wifi_station_initialize(void) { // 配置WiFi的配置信息 wifi_config_t wifi_config = { .sta = { .ssid = LIGHT_ESP_WIFI_SSID, .password = LIGHT_ESP_WIFI_PASS, // 启用WPA2模式,常用的WiFi连接方式 .threshold.authmode = WIFI_AUTH_WPA2_PSK, .pmf_cfg = { .capable = true, .required = false }, }, }; // WiFi工作模式设置为STA ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); // 设置WiFi工作模式 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); // 启动WiFi ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "wifi_station_initialize finished."); /* 等待连接建立(WIFI_CONNECTED_BIT)或连接失败的次数达到最大值(WIFI_FAIL_BIT)。 * 这些位通过 event_handler() 设置(详见上面)*/ EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); /* xEventGroupWaitBits() 返回调用前的 bits,因此我们可以测试实际发生了什么事件。 */ if (bits & WIFI_CONNECTED_BIT) { ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS); } else if (bits & WIFI_FAIL_BIT) { ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS); } else { ESP_LOGE(TAG, "UNEXPECTED EVENT"); } }3. tcpServer.h#ifndef TCP_SERVER #define TCP_SERVER #include #include #include #include #include #define PORT 3000 void create_tcp_server(); void process_tcp_client(); #endif4. tcpServer.c// // // #include #include "tcpServer.h" static struct sockaddr_in server_addr; static int server_socket = -1; static const char* TAG = "TCP SERVER"; void create_tcp_server(){ server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if(server_socket


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3